//
// Created by Ryan on 2020/11/28.
//

#ifndef CCOS_MULTIBOOT_H
#define CCOS_MULTIBOOT_H

#include "types.h"

typedef struct {
    uint32_v flags; // 版本信息
    /**
* 从 BIOS 获知的可用内存
*
* mem_lower 和 mem_upper 分别指出了低端和高端内存的大小，单位是。K
* 低端内存的首地址是 0 ，高端内存的首地址是 1M 。
* 低端内存的最大可能值是 640K
* 高端内存的最大可能值是最大值减去 1M 。但并不保证是这个值。
* 也就是说[0, mem_lower) 是低端内存大小, [1024K, mem_upper)是高端内存大小
*/
    uint32_v mem_lower;
    uint32_v mem_upper;

    uint32_v boot_device; // 指出引导程序从哪个磁盘设备载入的映像BIOSOS
    uint32_v cmdline;     // 内核命令行
    uint32_v mods_count;  // boot模块列表
    uint32_v mods_addr;

    /**
 * ELF 格式内核映像的 section 头表。包括每项的大小、一共有几项以及作为名字索引
 * 的字符串。
 */
    uint32_v num;
    uint32_v size;
    uint32_v addr;
    uint32_v shndx;

    /**
 * 以下两项指出保存由 BIOS 提供的内存分布的缓冲区的地址和长度
 * mmap_addr 是缓冲区的地址， mmap_length 是缓冲区的总大小
 * 缓冲区由一个或者多个下面的 mmap_entry_t 组成
 */
    uint32_v mmap_length;
    uint32_v mmap_addr;

    uint32_v drives_length;    // 指出第一个驱动器结构的物理地址
    uint32_v drives_addr;      // 指出第一个驱动器这个结构的大小
    uint32_v config_table;     // ROM 配置表
    uint32_v boot_loader_name; // boot loader 的名字
    uint32_v apm_table;        // APM 表
    uint32_v vbe_control_info;
    uint32_v vbe_mode_info;
    uint32_v vbe_mode;
    uint32_v vbe_interface_seg;
    uint32_v vbe_interface_off;
    uint32_v vbe_interface_len;

} __attribute__((packed)) multiboot_m;


/**
* size 是相关结构的大小，单位是字节，它可能大于最小值 20
* base_addr_low 是启动地址的低位，32base_addr_high 是高 32 位，启动地址总共有 64 位
* length_low 是内存区域大小的低位，32length_high 是内存区域大小的高 32 位，总共是 64 位
* type 是相应地址区间的类型，1 代表可用，所有其它的值代表保留区域 RAM
*/
typedef
struct mmap_entry_m {
    uint32_v size; // size 是不含 size 自身变量的大小
    uint32_v base_addr_low;
    uint32_v base_addr_high;
    uint32_v length_low;
    uint32_v length_high;
    uint32_v type;
} __attribute__((packed)) mmap_entry_m;

// 声明全局的 multiboot_t * 指针
extern multiboot_m *glb_mboot_ptr;

#endif //CCOS_MULTIBOOT_H
